home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part2 / 16144 < prev    next >
Encoding:
Text File  |  1996-08-05  |  4.3 KB  |  133 lines

  1. Path: news.compuserve.com!newsmaster
  2. From: RossBoylan@aol.com (Ross Boylan)
  3. Newsgroups: comp.lang.c++,comp.os.ms-windows.programmer.misc
  4. Subject: Re: Virtual function question (summary of answers)
  5. Date: Tue, 09 Apr 1996 19:22:45 GMT
  6. Organization: CompuServe Incorporated
  7. Message-ID: <4ked7o$8g3@dub-news-svc-1.compuserve.com>
  8. References: <4jp6e9$ou5@dub-news-svc-1.compuserve.com>
  9. NNTP-Posting-Host: ad06-115.compuserve.com
  10. X-Newsreader: Forte Free Agent 1.0.82
  11.  
  12. Problem:  To define the comparison operators <, <=, >, ==, etc in
  13. terms of one or two primitives (< and maybe ==), so that all classes
  14. for which the comparisons make sense only require definition of the
  15. primitives.
  16.  
  17. Solutions
  18. 1) The best solution I've seen is in the Standard Template library,
  19. e.g. (from function.h):
  20. template <class T>
  21. inline bool operator>=(const T& x, const T& y) {
  22.     return !(x < y);
  23. }
  24.  
  25. My original problem statement used member functions, but the symmetric
  26. free-standing functions are more appropriate to the comparison
  27. operators. 
  28.  
  29. 2)  The remaining solutions use member functions (Borland's library
  30. apparently does this) and create bogus functions which take abstract
  31. classes as arguments.  In the following, RBMagnitude::operator< is not
  32. virtual, so subclasses do not need to override it (they ignore it
  33. instead).
  34.  
  35. class RBMagnitude {
  36.    bool operator <(RBMagnitude& x) const 
  37.        {throw "Subclasses should override"; return 1;};  
  38.     // the throw is optional
  39.    int operator >(RBMagnitude& x) { return x<*this;};
  40. //etc
  41.  };
  42.  
  43. class Number : public RBMagnitude {
  44. private:
  45.     double myNumber;
  46. public:
  47.      virtual bool operator<(Number& x) const
  48.      {return myNumber < x.myNumber;}
  49. };
  50.  
  51.  
  52. 3) Several people suggested casting down as a possibility:
  53. class RBMagnitude {
  54.    virtual bool operator <(RBMagnitude& x) const = 0;
  55.    int operator >(RBMagnitude& x) { return x<*this;};
  56. //etc
  57.  };
  58.  
  59. class Number : public RBMagnitude {
  60. private:
  61.     double myNumber;
  62. public:
  63.      virtual bool operator<(RBMagnitude& x) const
  64.      {return myNumber < ((Number&) x).myNumber;}  
  65.     // we could dynamically test the class of x if we were being careful
  66. };
  67.  
  68. If the class is CObject derived we could have code like
  69.  { if (x.IsKindOf(RUNTIME_CLASS(Number))
  70.     return n < /* x might need casting?? */x.n;
  71.         else     return 0;  /* or throw exception*/ }
  72.  
  73. 4) My original problem defined all RBMagnitude operators as virtual.
  74. I have some potential subclasses which redefine all the inequality
  75. operators.  However, the gain in computing comparisons directly may be
  76. offset by the overhead of virtual functions, and it is probably
  77. clearner not to use virtual functions.
  78.  
  79. 5) Scott Meyer's new book, More Effective C++, has some material in
  80. item 33 which may be relevant (I haven't had a chance to look at it
  81. yet).
  82.  
  83. Thanks to
  84. pab@maui.com (Paul A. Billings)
  85. William E. Kempf      mailto:wekempf@marlton.1dc.com (work)
  86. Oliver Enseling                    e-mail: oliver@skypoint.com
  87.  Maruthi   NetQuest
  88. Saul Rosenberg   rosenberg@decus.org
  89.  
  90. Here's the original post, for reference.
  91. >I am trying to define, a la Smalltalk, a mix-in which defines the
  92. >various comparison operators in terms of one fundamental operator, <.
  93.  
  94.  
  95. >typedef int bool;
  96. >class RBMagnitude {
  97. >public:
  98. >//subclass should redefine < with appropriate types
  99. >    virtual bool operator<(const RBMagnitude&) const= 0;
  100. >    virtual bool operator>(const RBMagnitude& x) const {return  *this <
  101. >x;};
  102. >// and many more
  103. >};
  104.  
  105. >class A : public RBMagnitude {
  106. >public:
  107. >    virtual bool operator<(const A& a) const {return (this->n < a.n);};
  108. >private:
  109. >    int n;
  110. >};
  111.  
  112.  
  113. >class A test;
  114.  
  115. >This fails in MSVC++ 4.0 with the error that A is virtual because the
  116. >operator<(const RBMagnitude&) is not defined.
  117. >It looks to me as if this is because the operator< for A has a
  118. >different type signature (it uses an A rather than an RBMagnitude).
  119. >If so, the problem is the language definition, not Microsoft's
  120. >implementation.
  121.  
  122. >1) Is this interpretation correct? [yes, it is]
  123. >2) Is there any way around this problem?  Commenting out the
  124. >definition of RBMagnitude::operator< doesn't work, because
  125. >RBMagnitude::operator> requires it.  I suppose I could define a bogus
  126. >operator< which throws an exception, but this seems awkward (in
  127. >particular, if A and B are both RBMagnitudes and I ask A<B, I fail at
  128. >run time rather than compile time).
  129.  
  130. >I would appreciate e-mail; I'll summarize here.
  131.  
  132.  
  133.